package com.adv.util;

import java.io.File;
import java.io.FileWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import com.adv.vo.MailInfo;

import freemarker.template.Template;

/**
 * @ClassName: MailUtil
 * @Description: 邮件发送工具类
 * @author: WUQINGLONG
 * @date: 2016年9月20日 下午2:14:36
 */
public class MailUtil {
	private final Logger logger = LoggerFactory.getLogger(getClass());

	private ExecutorService service;

	private JavaMailSender sender;

	private FreeMarkerConfigurer freeMarkerConfigurer;

	private int poolSize = 1;

	public void setSender(JavaMailSender sender) {
		this.sender = sender;
	}

	public void setFreeMarkerConfigurer(FreeMarkerConfigurer freeMarkerConfigurer) {
		this.freeMarkerConfigurer = freeMarkerConfigurer;
	}

	public void setPoolSize(int poolSize) {
		this.poolSize = poolSize;
	}

	/**
	 * 
	 * @Title: sendEmail
	 * @Description: 发送邮件
	 * @param mail
	 * @return: void
	 */
	public void send(MailInfo mail) {
		MimeMessage message = convertMessage(mail);
		if (null == message) {
			return;
		}
		// 阻塞发送
		// sender.send(message);

		// 线程池发送
		if (null == service) {
			synchronized (logger) {
				if (null == service) {
					service = Executors.newFixedThreadPool(this.poolSize);
				}
			}
		}
		logger.debug("send mail to pool, mail info is: " + mail.toString());
		service.execute(new MailRunner(message));
	}

	private MimeMessage convertMessage(MailInfo mail) {
		if (null == mail) {
			logger.error("send mail no mail or helper info");
			return null;
		}
		try {
			MimeMessage message = sender.createMimeMessage();
			boolean multipart = ArrayUtils.isNotEmpty(mail.getAttachFile())
					|| !CollectionUtils.isEmpty(mail.getInlineMap());
			MimeMessageHelper helper = new MimeMessageHelper(message, multipart);
			helper.setFrom(mail.getSender());
			helper.setTo(mail.getReceivers());
			if (StringUtils.isNotBlank(mail.getTemplateName())) {
				Template template = freeMarkerConfigurer.getConfiguration().getTemplate(mail.getTemplateName());
				String htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(template, mail.getTemplateParam());
				helper.setText(htmlText, true);
				logger.debug("send mail use freemarktertemple is " + mail.getTemplateName());
				logger.debug("send mail resolved content is " + htmlText);
				if (!CollectionUtils.isEmpty(mail.getInlineMap())) {
					for (Entry<String, File> entry : mail.getInlineMap().entrySet()) {
						helper.addInline(entry.getKey(), entry.getValue());
					}
				}
			} else if (StringUtils.isNotBlank(mail.getContent())) {
				helper.setText(mail.getContent(), mail.isHtmlContent());
			}
			if (StringUtils.isNotBlank(mail.getSubject())) {
				helper.setSubject(mail.getSubject());
			}
			if (ArrayUtils.isNotEmpty(mail.getCc())) {
				helper.setCc(mail.getCc());
			}
			if (ArrayUtils.isNotEmpty(mail.getBcc())) {
				helper.setBcc(mail.getBcc());
			}
			if (StringUtils.isNotBlank(mail.getContendId())
					&& StringUtils.isBlank(helper.getMimeMessage().getContentID())) {
				helper.getMimeMessage().setContentID(mail.getContendId());
			}
			if (null != mail.getSendDate()) {
				helper.setSentDate(mail.getSendDate());
			} else {
				helper.setSentDate(new Date());
			}
			if (ArrayUtils.isNotEmpty(mail.getAttachFile())) {
				for (File file : mail.getAttachFile()) {
					FileSystemResource fileSystemResource = new FileSystemResource(file);
					helper.addAttachment(MimeUtility.encodeWord(file.getName()), fileSystemResource);
				}
			}
			helper.setValidateAddresses(true);
			return message;
		} catch (Exception e) {
			logger.error("send mail error in convert message: " + e);
		}
		return null;
	}

	private class MailRunner implements Runnable {
		private MimeMessage mimeMessage;

		public MailRunner(MimeMessage mimeMessage) {
			this.mimeMessage = mimeMessage;
		}

		public void run() {
			try {
				sender.send(this.mimeMessage);
				logger.debug("send mail ok! mail contentId is: " + this.mimeMessage.getContentID());
			} catch (Exception e) {
				logger.error("send mail error", e);
			}
		}
	}

	@SuppressWarnings("resource")
	public static void main(String[] args) throws Exception {
		String address = "wuqinglong@ovvitech.com", cc = "hellowql@126.com";
		ApplicationContext factory = new ClassPathXmlApplicationContext("spring_config.xml", "spring-app.xml",
				"spring-email.xml");
		MailUtil util = factory.getBean(MailUtil.class);
		MailInfo mail;
		// attach
		String attachFileName = new ClassPathResource("").getFile().getAbsolutePath() + "/哈哈.txt";
		System.out.println(attachFileName);
		File attachFile = new File(attachFileName);
		FileWriter fr = new FileWriter(attachFile);
		fr.write("中国 深圳");
		fr.close();
		attachFile.deleteOnExit();

		System.out.println("-----------附件测试---------");
		mail = new MailInfo();
		mail.setContendId(new Random().nextInt(100) + "");
		mail.setContent("hello world!");
		mail.setSubject("this is test!!! ");
		mail.setSender(address);
		mail.setReceivers(new String[] { address });
		mail.setCc(new String[] { cc });
		mail.setAttachFile(new File[] { new ClassPathResource("server.properties").getFile(), attachFile });
		util.send(mail);

		System.out.println("-----------freemarker测试---------");
		mail = new MailInfo();
		mail.setContendId(new Random().nextInt(100) + "");
		mail.setSubject("this is freemarker test!!! ");
		mail.setSender(address);
		mail.setReceivers(new String[] { address });
		mail.setCc(new String[] { cc });
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("username", "wuqinglong");
		param.put("password", "123456");
		Map<String, File> inlineMap = new HashMap<String, File>();
		inlineMap.put("background",
				new File(System.getProperty("user.dir") + "/WebContent/static/web/img/background.jpg"));
		mail.setTemplateName("register_success.html");
		mail.setTemplateParam(param);
		mail.setInlineMap(inlineMap);
		util.send(mail);
	}
}